import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/Addons.js';

const width = window.innerWidth;
const height = window.innerHeight;
let objects: any[] = [];
let isShiftDown = false;
let isSpaceDown = false;
let isMoving = false;
var targetPosition = new THREE.Vector3(0, 0, 0);
var timer = null;

// 创建一个三维场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);

// 创建一个相机
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.set(500, 800, 1300);
camera.lookAt(0, 0, 0); // 观察点


const rollOverGeo = new THREE.BoxGeometry(50, 50, 50);
const rollOverMaterial = new THREE.MeshBasicMaterial({ color: 0x999999, opacity: 0.5, transparent: true });
const rollOverMesh = new THREE.Mesh(rollOverGeo, rollOverMaterial);
scene.add(rollOverMesh);


// 创建网格模型对象
const map = new THREE.TextureLoader().load('1.jpg');
map.colorSpace = THREE.SRGBColorSpace;
const cubeGeo = new THREE.BoxGeometry(50, 50, 50);
const cubeMaterial = new THREE.MeshLambertMaterial({
  map: map,
})

// 创建一个网格平面
var gridHelper = new THREE.GridHelper(1000, 20);
scene.add(gridHelper);

const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();

const geometry = new THREE.PlaneGeometry(1000, 1000);
geometry.rotateX(- Math.PI / 2);
const plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ visible: false }));
scene.add(plane);

objects.push(plane);

// 创建光源
const ambientLight = new THREE.AmbientLight(0x606060, 3.0);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 8);
directionalLight.position.set(1, 0.75, 0.5);
scene.add(directionalLight);

const directionalHelper = new THREE.DirectionalLightHelper(directionalLight, 20, 0xff0000);
scene.add(directionalHelper);



// 创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true, //抗锯齿
});
renderer.setPixelRatio(window.devicePixelRatio); // 设置像素比
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

renderer.render(scene, camera);

// 设置相机轨道控件
const controls = new OrbitControls(camera, renderer.domElement);
controls.enabled = false;
controls.update();
controls.addEventListener('change', () => {
  renderer.render(scene, camera);
})

window.onresize = function () {
  renderer.setSize(window.innerWidth, window.innerHeight);
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.render(scene, camera);
}

document.addEventListener('pointermove', (event) => {
  pointer.set((event.clientX / window.innerWidth) * 2 - 1, - (event.clientY / window.innerHeight) * 2 + 1);
  raycaster.setFromCamera(pointer, camera);
  const intersects = raycaster.intersectObjects(objects, false);

  if (intersects.length > 0) {
    const intersect = intersects[0];
    rollOverMesh.position.copy(intersect.point).add((intersect as any).face.normal);
    rollOverMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);

    renderer.render(scene, camera);
  }
});

document.addEventListener('pointerdown', (event) => {
  pointer.set((event.clientX / window.innerWidth) * 2 - 1, - (event.clientY / window.innerHeight) * 2 + 1);

  raycaster.setFromCamera(pointer, camera);
  const intersects = raycaster.intersectObjects(objects, false);
  if (intersects.length > 0) {
    const intersect = intersects[0];

    if (isShiftDown && !isSpaceDown) {
      if (intersect.object !== plane) {
        scene.remove(intersect.object);
        objects.splice(objects.indexOf(intersect.object), 1);
      }
    } else if (!isSpaceDown) {
      const voxel = new THREE.Mesh(cubeGeo, cubeMaterial);
      voxel.position.copy(intersect.point).add((intersect as any).face.normal);
      voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
      scene.add(voxel);

      objects.push(voxel);
    }
    renderer.render(scene, camera);

  }
})
document.addEventListener('keydown', (event) => {
  isMoving = false;
  cancelAnimationFrame(timer!);
  switch (event.keyCode) {
    case 16: {
      isShiftDown = true;
      rollOverMesh.visible = false;
    }; break;
    case 32: {
      isSpaceDown = true;
      rollOverMesh.visible = false;
      controls.enabled = true;
    } break;
  }
});
document.addEventListener('keyup', (event) => {
  switch (event.keyCode) {
    case 16: {
      isShiftDown = false
      rollOverMesh.visible = true;
    }; break;
    case 32: {
      isSpaceDown = false;
      rollOverMesh.visible = true;
      controls.enabled = false;
    } break;
    case 37: {
      isMoving = true;
      controls.enabled = false;
      targetPosition.set(-1606, 0.42, -13.6)
      animate();
    } break;
    case 38: {
      isMoving = true;
      controls.enabled = false;
      targetPosition.set(-0.006, 1605, 28.4)
      animate();
    } break;
    case 39: {
      isMoving = true;
      controls.enabled = false;
      targetPosition.set(1604, -1.83, 66.1)
      animate();
    } break;
    case 40: {
      isMoving = true;
      controls.enabled = false;
      targetPosition.set(-10.4, -1.59, 1606)
      animate();
    } break;
    case 82: {
      for (let i = 1; i < objects.length; i++) {
        scene.remove(objects[i])
      }
      objects = [objects[0]]
      isMoving = true;
      targetPosition.set(500, 800, 1300)
      animate();
      renderer.render(scene, camera);
    } break;
    case 86: {
      isMoving = true;
      targetPosition.set(500, 800, 1300)
      animate();
      renderer.render(scene, camera);
    } break;
  }
});



function animate() {
  timer = requestAnimationFrame(animate);
  if (isMoving) {
    camera.position.lerp(targetPosition, 0.1);
    if (camera.position.distanceTo(targetPosition) < 0.01) {
      camera.position.copy(targetPosition);
      isMoving = false;
      cancelAnimationFrame(timer);
    }
    controls.update(); // 更新OrbitControls
  }
}

